package com.example.ailiyuncloud.service.Impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.ailiyuncloud.dto.CommodityConfigDto;
import com.example.ailiyuncloud.dto.CommodityOrderDTO;
import com.example.ailiyuncloud.dto.CommoditySkuByStagesDTO;
import com.example.ailiyuncloud.dto.CommoditySkuDto;
import com.example.ailiyuncloud.mapper.CommodityOrderMapper;
import com.example.ailiyuncloud.req.QueryCommodityOrderServiceReq;
import com.example.ailiyuncloud.service.CommodityByStagesService;
import com.example.ailiyuncloud.service.CommodityOrderService;
import com.example.ailiyuncloud.service.CommoditySkuConfigService;
import com.example.ailiyuncloud.service.CommoditySkuService;
import com.example.ailiyuncloud.vo.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.util.*;
import java.util.stream.Collectors;

import static com.example.ailiyuncloud.service.Impl.CommoditySkuServiceImpl.generateId;

/**
 * @Author: lqj
 * @Date: 2024/05/29/14:05
 * @Description:
 */
@Service
public class CommodityOrderServiceImpl implements CommodityOrderService {

    public static final String OD = "OD-";

    @Autowired
    private CommodityOrderMapper commodityOrderMapper;

    @Autowired
    private CommoditySkuService commoditySkuService;

    @Autowired
    private RedisTemplate<String, Object> stringRedisTemplate;


    @Autowired
    private CommoditySkuConfigService commoditySkuConfigService;


    @Autowired
    private CommodityByStagesService commodityByStagesService;

    public static final Page pages = new Page(0, -1);

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addCommodityOrderService(List<AddCommodityOrderVO> addCommodityOrderVOList) {
        if (addCommodityOrderVOList.isEmpty()) {
            throw new RuntimeException("参数为空或参数不正确，请检查！");
        }
        // todo 单个用户或者单个手机号下单上限为100个商品
        //校验分期id是否都存在，不存在则报错
        QueryCommodityByStagesVO queryCommodityByStagesVO = new QueryCommodityByStagesVO();
        List<Long> commodityByIdList = addCommodityOrderVOList.stream().distinct().map(AddCommodityOrderVO::getCommodityById).collect(Collectors.toList());
        queryCommodityByStagesVO.setById(commodityByIdList);
        IPage<CommoditySkuByStagesDTO> commoditySkuByStagesDTOIPage = commodityByStagesService.queryCommodityByStagesService(pages, queryCommodityByStagesVO);
        if (commoditySkuByStagesDTOIPage.getTotal() != commodityByIdList.size()) {
            throw new RuntimeException("商品分期项不存在，请检查！");
        }
        // 校验配置id是否都存在，不存在则报错
        QueryCommoditySkuConfigVO queryCommoditySkuConfigVO = new QueryCommoditySkuConfigVO();
        List<Long> commodityConfigIdCollect = addCommodityOrderVOList.stream().distinct().map(AddCommodityOrderVO::getCommodityConfigId)
                .collect(Collectors.toList());
        queryCommoditySkuConfigVO.setConfigId(commodityConfigIdCollect);
        IPage<CommodityConfigDto> commodityConfigDtoIPage = commoditySkuConfigService.queryCommoditySkuConfigService(pages, queryCommoditySkuConfigVO);
        if (commodityConfigDtoIPage.getRecords().size() != commodityConfigIdCollect.size()) {
            throw new RuntimeException("商品配置不存在，请检查！");
        }
        QueryCommoditySkuVO queryCommoditySkuVO = new QueryCommoditySkuVO();
        queryCommoditySkuVO.setSkuId(addCommodityOrderVOList.stream()
                .map(AddCommodityOrderVO::getSkuId)
                .collect(Collectors.toList()));
        IPage<CommoditySkuDto> listPage = commoditySkuService.queryCommoditySkuService(pages, queryCommoditySkuVO);
        if (ObjectUtils.isEmpty(listPage.getRecords())) {
            throw new RuntimeException("SKU数据为空或不存在，请检查！");
        }
        //查询出未逻辑删除的sku
        List<CommoditySkuDto> records = listPage.getRecords();
        Map<String, CommoditySkuDto> collect = records.stream().collect(Collectors.toMap(CommoditySkuDto::getSkuId, o -> o));
        addCommodityOrderVOList.forEach(commodityOrder -> {
            if (!isValidPhoneNumber(commodityOrder.getOrderPhone())) {
                throw new RuntimeException("手机号不正确请检查！");
            }
            String skuId = commodityOrder.getSkuId();
            CommoditySkuDto commoditySkuDto = collect.get(skuId);
            if (ObjectUtils.isEmpty(commoditySkuDto)) {
                throw new RuntimeException(skuId + "下单失败，该商品不存在或已下架请更换商品");
            }
            CommodityOrderDTO commodityOrderDTO = new CommodityOrderDTO();
            commodityOrderDTO.setOrderId(OD + generateId());
            commodityOrderDTO.setSkuId(skuId);
            commodityOrderDTO.setCommodityName(commoditySkuDto.getCommodityName());
            commodityOrderDTO.setCommodityNumber(commodityOrder.getCommodityNumber());
            commodityOrderDTO.setCommodityType(commoditySkuDto.getCommodityTopIc());
            commodityOrderDTO.setCommodityAmount(commoditySkuDto.getCommodityPrice());
            commodityOrderDTO.setOrderNotes(commodityOrder.getOrderNotes());
            commodityOrderDTO.setOrderAddress(commodityOrder.getOrderAddress());
            commodityOrderDTO.setOrderPhone(commodityOrder.getOrderPhone());
            commodityOrderDTO.setCommodityConfigId(commodityOrder.getCommodityConfigId());
            commodityOrderDTO.setCommodityById(commodityOrder.getCommodityById());
            commodityOrderMapper.insert(commodityOrderDTO);
            try {
                commoditySkuService.deductionsCommoditySkuService(Arrays.asList(new DeductionsCommoditySkuVO().set(skuId, commodityOrder.getCommodityNumber())));
            } catch (Exception e) {
                throw new RuntimeException("扣减库存失败");
            }
        });
        refreshOrderRedis();
    }

    @Override
    public List<QueryCommodityOrderServiceReq> queryCommodityOrderService(Page page, QueryCommodityOrderVO queryCommodityOrderVO) {
        List<QueryCommodityOrderServiceReq> queryCommodityOrderServiceReqList = new ArrayList<>(16);

        if (page.getCurrent() < 1 && queryCommodityOrderVO.isEmpty()) {
            //list.addAll(stringRedisTemplate.opsForList().range(OD, 0, 10));
        } else {

            IPage<CommodityOrderDTO> commodityOrderListInfo = commodityOrderMapper.getCommodityOrderListInfo(page, queryCommodityOrderVO);
            QueryCommoditySkuConfigVO queryCommoditySkuConfigVO = new QueryCommoditySkuConfigVO();
            queryCommoditySkuConfigVO.setConfigId(commodityOrderListInfo.getRecords().stream().distinct()
                    .map(CommodityOrderDTO::getCommodityConfigId).collect(Collectors.toList()));
            IPage<CommodityConfigDto> commodityConfigDtoIPage = commoditySkuConfigService.queryCommoditySkuConfigService(pages, queryCommoditySkuConfigVO);
            Map<String, CommodityConfigDto> commodityConfigDtoMap = commodityConfigDtoIPage.getRecords().stream().collect(Collectors.toMap(CommodityConfigDto::getSkuId, o -> o));

            QueryCommodityByStagesVO queryCommodityByStagesVO = new QueryCommodityByStagesVO();
            List<Long> commodityByIdList = commodityOrderListInfo.getRecords().stream().distinct().map(CommodityOrderDTO::getCommodityById).collect(Collectors.toList());
            queryCommodityByStagesVO.setById(commodityByIdList);
            IPage<CommoditySkuByStagesDTO> commoditySkuByStagesDTOIPage = commodityByStagesService.queryCommodityByStagesService(pages, queryCommodityByStagesVO);
            Map<String, CommoditySkuByStagesDTO> commoditySkuByStagesDTOMap = commoditySkuByStagesDTOIPage.getRecords().stream().collect(Collectors.toMap(CommoditySkuByStagesDTO::getSkuId, o -> o));
            commodityOrderListInfo.getRecords().stream().forEach(commodityOrderDTO -> {
                QueryCommodityOrderServiceReq queryCommodityOrderServiceReq = new QueryCommodityOrderServiceReq();
                BeanUtils.copyProperties(commodityOrderDTO, queryCommodityOrderServiceReq);
                queryCommodityOrderServiceReq.setCommodityOrderConfig(commodityConfigDtoMap.get(commodityOrderDTO.getSkuId()));
                queryCommodityOrderServiceReq.setCommoditySkuByStages(commoditySkuByStagesDTOMap.get(commodityOrderDTO.getSkuId()));
                queryCommodityOrderServiceReqList.add(queryCommodityOrderServiceReq);
            });


            // 查询商品配置接口

        }
        return queryCommodityOrderServiceReqList;
    }


    /**
     * 校验手机号接口
     *
     * @param phoneNumber 手机号
     * @return
     */
    public static boolean isValidPhoneNumber(String phoneNumber) {
        if (phoneNumber == null) {
            return true;
        }
        // 正则表达式，校验以1开头的11位数字
        phoneNumber = phoneNumber.replaceAll("\\s+", "");
        return phoneNumber != null && phoneNumber.matches("^1\\d{10}$");
    }

    /**
     * 加载缓存接口
     */
    public void refreshOrderRedis() {
        List<CommodityOrderDTO> records = commodityOrderMapper.selectPage(new Page<>(0, 100),
                        Wrappers.<CommodityOrderDTO>lambdaQuery()
                                .orderByDesc(CommodityOrderDTO::getCreateTime))
                .getRecords();
        stringRedisTemplate.delete(OD);
        stringRedisTemplate.opsForList().rightPushAll(OD, records);
    }
}
